<template>
  <div>
    <!-- 文档树形结构展示 -->
    <el-tree
      :data="treeData"
      node-key="id"
      :default-expand-all="true"
      highlight-current
      @node-click="onNodeClick"
      @node-contextmenu="onRightClick"
    />

    <!-- 自定义右键菜单 -->
    <div v-if="menuVisible" class="context-menu" :style="{ top: menuY + 'px', left: menuX + 'px' }">
      <ul>
        <li @click="onRename">重命名</li>
        <li @click="onDelete">删除文档</li>
        <li @mouseenter="showMoveSubmenu = true" @mouseleave="showMoveSubmenu = false">
          移动标签 ▸
          <ul class="submenu" v-if="showMoveSubmenu">
            <li v-for="tag in allTags" :key="tag.id" @click.stop="moveToTag(tag)">
              {{ tag.name }}
            </li>
          </ul>
        </li>
        <li @click="onDownload">下载文档</li>
      </ul>
    </div>

    <!-- 重命名弹窗 -->
    <el-dialog v-model="renameDialogVisible" title="重命名文档" width="30%">
      <el-input v-model="renameInput" placeholder="请输入新名称" />
      <template #footer>
        <el-button @click="renameDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="renameDoc">确认</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import service from '@/utils/request'
import { deleteDoc, renameDoc as apiRenameDoc, moveTag, downloadDoc } from '@/api/files'
import { useDocsStore } from '@/stores/DocsStore.js'
import { ElMessage, ElMessageBox } from 'element-plus'

const router = useRouter()

const treeData = ref([])
const menuVisible = ref(false)
const menuX = ref(0)
const menuY = ref(0)
const selectedDoc = ref(null)

const renameDialogVisible = ref(false)
const renameInput = ref('')
const showMoveSubmenu = ref(false)
const allTags = ref([])

const docStore = useDocsStore()

watch(
  () => docStore.needsRefresh,
  async (val) => {
    if (val) {
      await docStore.fetchDocs().finally(() => {
        treeData.value = docStore.groupedDocs
        docStore.needsRefresh = false
      })
    }
  },
)

onMounted(async () => {
  await docStore.fetchDocs()
  treeData.value = docStore.groupedDocs
  const tagListRes = await service.get('/tags')
  allTags.value = tagListRes.data
})

const onNodeClick = (data) => {
  if (data.isDoc) {
    router.push(`/docs/view/${data.id}`)
  }
}

function onRightClick(event, data, node) {
  if (!data.isDoc) return
  selectedDoc.value = data.raw
  menuX.value = event.clientX
  menuY.value = event.clientY
  menuVisible.value = true
  document.addEventListener('click', closeContextMenu)
}

function closeContextMenu() {
  menuVisible.value = false
  document.removeEventListener('click', closeContextMenu)
}

function onRename() {
  renameInput.value = selectedDoc.value.name
  renameDialogVisible.value = true
  closeContextMenu()
}

async function renameDoc() {
  const newName = renameInput.value.trim()
  if (!newName) {
    ElMessage.error('文档名不能为空')
    return
  }
  if (newName && newName !== selectedDoc.value.name) {
    try {
      await apiRenameDoc(selectedDoc.value.id, newName)
    } catch (err) {
      ElMessage.error('重命名失败，' + err.message)
    } finally {
      renameDialogVisible.value = false
      docStore.triggerRefresh()
    }
  }
}

async function onDelete() {
  const doc = selectedDoc.value
  try {
    await ElMessageBox.confirm(`确定要删除文档「${doc.name}」吗？此操作无法撤销。`, '删除确认', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning',
    })
    await deleteDoc(doc.id)
    ElMessage.success('删除成功')
  } catch (err) {
    if (err !== 'cancel') {
      ElMessage.error('删除失败')
    }
  } finally {
    docStore.triggerRefresh()
    closeContextMenu()
  }
}

async function moveToTag(tag) {
  const doc = selectedDoc.value
  try {
    await moveTag(doc.id, tag.id)
    closeContextMenu()
  } catch (err) {
    ElMessage.error('移动失败')
  } finally {
    docStore.triggerRefresh()
  }
}

async function onDownload() {
  const doc = selectedDoc.value
  try {
    const response = await downloadDoc(doc.id)
    const blob = new Blob([response.data])
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = doc.name + '.' + doc.type
    link.click()
    URL.revokeObjectURL(url)
  } catch (err) {
    console.log(err)
    ElMessage('下载失败')
  }
}
</script>

<style scoped>
.context-menu {
  position: fixed;
  background-color: white;
  border: 1px solid #dcdfe6;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  z-index: 9999;
  border-radius: 4px;
  padding: 4px 0;
  width: 140px;
}
.context-menu ul {
  margin: 0;
  padding: 0;
  list-style: none;
  position: relative;
}
.context-menu li {
  padding: 8px 16px;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
}
.context-menu li:hover {
  background-color: #f5f7fa;
}
.submenu {
  position: absolute;
  top: 0;
  left: 100%;
  margin-left: -4px;
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  min-width: 140px;
  z-index: 10000;
}
</style>
